# 存放并维护公共信息

from threading import Lock
import time


class PublicContext:
    _newest_tick_time = '07:00:00'
    tick_time_lock = Lock()
    _latest_tick_data = {}
    latest_tick_data_lock = Lock()
    get_current_time = None
    trader = None
    logger = None

    def __init__(self, mode='asyn'):
        self._newest_tick_time = '07:00:00'
        self.tick_time_lock = Lock()
        self._latest_tick_data = {}
        self.latest_tick_data_lock = Lock()
        self.get_current_time = None
        self.trader = None
        self.logger = None
        self.set_run_mode(mode)

    def set_run_mode(self, mode):
        if mode == 'syn':
            self.get_current_time = self.get_actual_time_syn
        else:
            self.get_current_time = self.get_actual_time_asyn

    def process_md(self, md):
        # 更新最新tick时间
        if md.time > self._newest_tick_time:
            with self.tick_time_lock:
                self._newest_tick_time = md.time
        # 更新最新行情记录
        with self.latest_tick_data_lock:
            if md.inst_id not in self._latest_tick_data.keys() or \
                    md.time > self._latest_tick_data[md.inst_id].time:
                self._latest_tick_data[md.inst_id] = md
                self.trader.check_order(md.inst_id)

    # 记录日志
    def log_message(self, msg):
        self.logger.log_message(msg)

    def send_order(self, order):
        return self.trader.send_order(order)

    @property
    def newest_tick_time(self):
        with self.tick_time_lock:
            newest_tick = self._newest_tick_time
        return newest_tick

    @staticmethod
    def get_actual_time_asyn():
        return time.strftime("%H:%M:%S", time.localtime())

    def get_actual_time_syn(self):
        return self.newest_tick_time

    # 这是一个不考虑线程安全的版本
    def get_order_book(self, inst_id):
        # with self.latest_tick_data_lock:
        md = self._latest_tick_data[inst_id]
        bid = md.b1_p
        bid_v = md.b1_v
        ask = md.a1_p
        ask_v = md.a1_v
        return bid, bid_v, ask, ask_v

    # 查询当前市场价格（线程安全）
    def get_market_price(self, inst_id):
        with self.latest_tick_data_lock:
            price = self._latest_tick_data[inst_id].price
        return price

    def get_position(self, strategy_name):
        return self.trader.get_position(strategy_name)


